using UnityEngine;
using System.Collections;

public class WaypointControl : MonoBehaviour
{
    #region Attributes

    public bool forward = false;
    public bool back = false;
    public bool left = false;
    public bool right = false;

    #endregion

    #region Methods

    public Vector3 FindNextWaypoint(Vector3 targetPosition)
    {
        Vector3 direction = this.GetDirection(targetPosition);
        return this.FindWaypointPosition(direction);
    }

    public Vector3 FindWaypointPosition(Vector3 directionToSearch)
    {
        Vector3 waypointPosition = Vector3.zero;

        int layerMask = TagConstants.LAYER_MARKS;
       
        /* Check Player Hit */
        RaycastHit hit;
        if (Physics.Raycast(this.transform.position, directionToSearch, out hit, float.MaxValue, layerMask))
            waypointPosition = hit.collider.gameObject.transform.position;
        
        if (hit.collider != null)
            Debug.Log("Waypoint:" + this.name + " To: " + hit.collider.name + "Point: " + waypointPosition + " For: " + directionToSearch);
        else
            Debug.Log("Waypoint:" + this.name + "Point: " + waypointPosition + " For: " + directionToSearch);
        return waypointPosition;
    }

    public Vector3[] GetDirections()
    {
        ArrayList direcctions = new ArrayList(4);

        if (this.forward)
            direcctions.Add(Vector3.forward);
        if (this.back)
            direcctions.Add(Vector3.back);
        if (this.left)
            direcctions.Add(Vector3.left);
        if (this.right)
            direcctions.Add(Vector3.right);

        return (Vector3[])direcctions.ToArray( typeof(Vector3) );
    }

    public Vector3 GetDirection(Vector3 targetPosition)
    {
        Vector3 direction = Vector3.zero;
        float? lastDistance = null; 
        Vector3 targetDirection = targetPosition.normalized;

        if (this.forward)
            this.UpdateDirection(Vector3.forward, targetDirection, ref direction, ref lastDistance);
        if (this.back)
            this.UpdateDirection(Vector3.back, targetDirection, ref direction, ref lastDistance);
        if (this.left)
            this.UpdateDirection(Vector3.left, targetDirection, ref direction, ref lastDistance);
        if (this.right)
            this.UpdateDirection(Vector3.right, targetDirection, ref direction, ref lastDistance);
        
        return direction;
    }

    private void UpdateDirection(Vector3 zoneDirection, Vector3 targetDirection, ref Vector3 direction, ref float? lastDistance)
    {
        Vector3 distance = targetDirection - zoneDirection;
        float distanceValue = distance.magnitude;

        if (lastDistance == null || distanceValue < lastDistance)
        {
            direction = zoneDirection;
            lastDistance = distanceValue;
        }
    }

    #endregion

    #region Unity Methods

    void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        if (this.forward)
            Gizmos.DrawRay(this.transform.position, Vector3.forward);
        if (this.back)
            Gizmos.DrawRay(this.transform.position, Vector3.back);
        if (this.left)
            Gizmos.DrawRay(this.transform.position, Vector3.left);
        if (this.right)
            Gizmos.DrawRay(this.transform.position, Vector3.right);
    }

    #endregion
}
